import Vue from 'vue'
import axios from 'axios'
import store from '@/store'
import router from '@/router'
import storage from 'store'
import { VueAxios } from './axios'
import { ACCESS_TOKEN } from '@/store/mutation-types'

// 创建 axios 实例
const request = axios.create({
  // API 请求的默认前缀
  baseURL: process.env.VUE_APP_API_BASE_URL,
  timeout: 6000 // 请求超时时间
})

// 异常拦截处理器
const errorHandler = (error) => {
  if (error.response) {
    const data = error.response.data
    Vue.prototype.$notification['warning']({
      message: data.msg || error.response.statusText,
      description: data.desc || error.response.statusText + '(' + error.response.status + ')',
      duration: 3
    })
  } else {
    Vue.prototype.$notification['warning']({
      message: error.toString(),
      duration: 3
    })
  }
  return Promise.reject(error)
}

// request interceptor
request.interceptors.request.use(config => {
  const token = storage.get(ACCESS_TOKEN)
  // 如果 token 存在
  // 让每个请求携带自定义 token 请根据实际情况自行修改
  if (token) {
    config.headers['Access-Token'] = token
  }
  config.url = config.baseURL + config.url.replace(/^\/+/, '')
  return config
}, errorHandler)

// response interceptor
request.interceptors.response.use((response) => {
  try {
    // Create the performance observer.
    const po = new PerformanceObserver((list) => {
      for (const entry of list.getEntries()) {
        // Logs all server timing data for this response
        console.debug('Server Timing', entry)
      }
    })
    // Start listening for `navigation` entries to be dispatched.
    po.observe({ type: 'navigation', buffered: true })
  } catch (e) {
    // Do nothing if the browser doesn't support this API.
  }

  if (response.data === '') {
    const error = new Error(response.statusText)
    error.response = response
    error.code = response.status
    error.desc = response.statusText
    // 统一做全局错误处理
    Vue.prototype.$notification['warning']({
      message: error + '(' + error.code + ')',
      description: error.desc || '请求出现错误，请稍后再试',
      duration: 3
    })
    return Promise.reject(error)
  } else if (response.data.code !== 0) {
    const error = new Error(response.data.msg)
    error.response = response
    error.code = response.data.code
    error.desc = response.data.desc
    // 统一做全局错误处理
    Vue.prototype.$notification['error']({
      message: error.message,
      description: error.desc,
      duration: 3
    })
    if (response.data.code === 20001) {
      store.dispatch('Logout').then(() => {
        router.push({ name: 'login', query: { redirect: router.history.current.fullPath } })
      })
    } else {
      return Promise.reject(error)
    }
  } else {
    return Promise.resolve(response)
  }
}, errorHandler)

const installer = {
  vm: {},
  install (Vue) {
    Vue.use(VueAxios, request)
  }
}

export default request

export {
  installer as VueAxios,
  request as axios
}
